use glass_expand::reflect_attribute::{NameAttr, ReflectAttr};
use proc_macro::TokenStream;
use syn::parse_macro_input;

macro_rules! convert_expand_result {
    ($e:expr) => {
        match $e {
            Ok(val) => val.into(),
            Err(err) => err.into_compile_error().into(),
        }
    };
}

#[proc_macro_derive(Reflect, attributes(reflect, name))]
pub fn derive_reflect(input: TokenStream) -> TokenStream {
    let expand_result = glass_expand::reflect_derive::expand(&mut parse_macro_input!(input));
    convert_expand_result!(expand_result)
}

#[proc_macro_attribute]
pub fn reflect(attr: TokenStream, item: TokenStream) -> TokenStream {
    let mut attr = parse_macro_input!(attr as ReflectAttr);
    let mut item = parse_macro_input!(item as syn::Item);
    let expand_result = glass_expand::reflect_attribute::expand(&mut attr, &mut item);
    convert_expand_result!(expand_result)
}

#[proc_macro_attribute]
pub fn name(attr: TokenStream, item: TokenStream) -> TokenStream {
    let _attr = parse_macro_input!(attr as NameAttr);
    item
}
